package org.grottarossa.data;


import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

import org.grottarossa.data.exception.DataSourceException;
import org.grottarossa.data.exception.QueryException;
import org.grottarossa.driver.ECMBuilderTemplate;

public abstract class DataSource
{
	protected Map<String, Class<?>> m_fields;
	protected ECMBuilderTemplate m_builder;

	public Query getQuery(String field, QueryFilter filter) throws QueryException
	{

		@SuppressWarnings("rawtypes")
		Constructor con = null;
		Query query = null;
		Class<?> query2execute = m_fields.get(field);

		try
		{
			con = query2execute.getConstructor(ECMBuilderTemplate.class);
		}
		catch (SecurityException e)
		{
			throw new QueryException(e.getMessage());
		}
		catch (NoSuchMethodException e)
		{
			throw new QueryException(e.getMessage());
		}

		try
		{
			query = (Query) con.newInstance(m_builder);
			query.setField(field);
			query.setFilter(filter);
			return query;
		}
		catch (IllegalArgumentException e)
		{
			throw new QueryException(e.getMessage());
		}
		catch (InstantiationException e)
		{
			throw new QueryException(e.getMessage());
		}
		catch (IllegalAccessException e)
		{
			throw new QueryException(e.getMessage());
		}
		catch (InvocationTargetException e)
		{
			throw new QueryException(e.getMessage());
		}
	}

	protected abstract void addManagedFields() throws DataSourceException;

	public DataSource() throws DataSourceException
	{
	}

	protected void addField(String field, Class<?> query)
	{
		this.m_fields.put(field, query);
	}

	public boolean manageField(String field)
	{
		return m_fields.containsKey(field);
	}

	public void initialize(ECMBuilderTemplate builder) throws DataSourceException
	{
		m_fields = new HashMap<String, Class<?>>();
		m_builder = builder;
		addManagedFields();
	}

}
